﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeSample.Utils
{
    class RTFEditor
    {
        public RTFEditor()
        { 
        
        }

        public string RemoveLeadingSentenceSpace(string RTFText)
        {
            List<int> leadingSpaceCountList = this.GetLeadingSpaceCountList(RTFText);
            int spaceCount2BRemove = this.GetTheLeastOf(leadingSpaceCountList);
            string neededReplaceString = @"\ltrch";

            for (; spaceCount2BRemove > 0; --spaceCount2BRemove)
            {
                neededReplaceString += " ";
            }

            RTFText = RTFText.Replace(neededReplaceString, @"\ltrch");

            return RTFText;
        }

        public string RemoveLeadingSentenceTab(string RTFText)
        {
            List<int> leadingTabCountList = this.GetLeadingTabCountList(RTFText);
            int tabCount2BRemove = this.GetTheLeastOf(leadingTabCountList);
            string neededReplaceString = @"\ltrch";

            for (; tabCount2BRemove > 0; --tabCount2BRemove)
            {
                neededReplaceString += @" \tab";
            }

            RTFText = RTFText.Replace(neededReplaceString, @"\ltrch");

            return RTFText;
        }

        private string RemoveSpaceFromNewLineMark(string RTFText, int spaceCount)
        {
            int spaceIndex = 0;

            while (RTFText[spaceIndex] != ' ')
                ++spaceIndex;

            ++spaceIndex;
            while (RTFText[spaceIndex] != ' ')
                ++spaceIndex;

            string newRTFText = RTFText.Substring(0, spaceIndex) + RTFText.Substring(spaceIndex + spaceCount);
            return newRTFText;
        }
        /// <summary>
        /// Count leading space from the beginning of line, after \ltrch
        /// </summary>
        /// <param name="aSubStringOfRTFText"></param>
        /// <returns></returns>
        public int CountLeadingSpace(string aSubStringOfRTFText)
        {
            int count = 0;

            if (aSubStringOfRTFText != "")
            {
                while (aSubStringOfRTFText[count] == ' ')
                    ++count;
                --count; // subtract the space of rich text format
            }

            return count;
        }
        /// <summary>
        /// Count leading tab from the beginning of line, after \ltrch
        /// </summary>
        /// <param name="aSubStringOfRTFText"></param>
        /// <returns></returns>
        public int CountLeadingTab(string aSubStringOfRTFText)
        {
            int index = 0;
            int count = 0;

            if (aSubStringOfRTFText != "")
            {
                while (aSubStringOfRTFText.Substring(index + 1, 5).Equals(@"\tab "))
                {
                    ++count;
                    index += 5;
                }
            }

            return count;
        }

        private List<int> GetLeadingSpaceCountList(string RTFText)
        {
            List<int> leadingSpaceCountList = new List<int>();
            string tempRTFText = RTFText;
            int index2Go = 0;
            int spaceCount = 0;

            do
            {
                index2Go = tempRTFText.IndexOf(@"\ltrch") + 6;
                if (index2Go < 6)
                    break;
                tempRTFText = tempRTFText.Substring(index2Go); // move to the start of first line
                spaceCount = this.CountLeadingSpace(tempRTFText); // count leading space
                if (spaceCount > 0)
                {
                    leadingSpaceCountList.Add(spaceCount); // add count number to list

                    index2Go = tempRTFText.IndexOf(@"\par}");
                    tempRTFText = tempRTFText.Substring(index2Go); // move to the end of line
                }
                else if (spaceCount == 0) // when line has no leading space
                {
                    if (tempRTFText[1] != '}') // if the line is not empty
                        leadingSpaceCountList.Add(spaceCount);
                }
            }
            while (spaceCount >= 0);

            return leadingSpaceCountList;
        }

        private List<int> GetLeadingTabCountList(string RTFText)
        {
            List<int> leadingTabCountList = new List<int>();
            string tempRTFText = RTFText;
            int index2Go = 0;
            int tabCount = 0;

            do
            {
                index2Go = tempRTFText.IndexOf(@"\ltrch") + 6;
                if (index2Go < 6)
                    break;
                tempRTFText = tempRTFText.Substring(index2Go); // move to the start of first line
                tabCount = this.CountLeadingTab(tempRTFText); // count leading space
                if (tabCount > 0)
                {
                    leadingTabCountList.Add(tabCount); // add count number to list

                    index2Go = tempRTFText.IndexOf(@"\par}");
                    tempRTFText = tempRTFText.Substring(index2Go); // move to the end of line
                }
                else if (tabCount == 0) // when line has no leading space
                {
                    if (tempRTFText[1] != '}') // if the line is not empty
                        leadingTabCountList.Add(tabCount);
                }
            }
            while (tabCount >= 0);

            return leadingTabCountList;
        }

        public bool IsXML(string RTFText)
        {
            int openBraceCount = 0;
            int lineCount = this.CountLine(RTFText);

            for (int i = 0; i < RTFText.Length; i++)
            {
                if (RTFText[i] == '<')
                    ++openBraceCount;
            }

            if (((float)openBraceCount / lineCount) >= (2.0 / 3.0))
                return true;
            else
                return false;
        }

        private int CountLine(string RTFText)
        {
            string tempRTFText = RTFText;
            int lineCount = 0;

            while (tempRTFText.Contains(@"\par}")) // \par} is end of every line
            {
                ++lineCount;
                tempRTFText = tempRTFText.Substring(tempRTFText.IndexOf(@"\par}") + 5);
            }

            return lineCount;
        }

        private int GetIndexOfFirstSpace(string RTFText)
        {
            int index = 0;

            while (RTFText[index] != ' ')
                ++index;

            return index;
        }

        public bool IsSpaceFormatNeeded(string RTFText)
        {
            List<int> leadingSpaceCountList = this.GetLeadingSpaceCountList(RTFText);
            int theLeast = 0;
            bool needFormat = false;

            if (leadingSpaceCountList.Count > 0)
            {
                theLeast = this.GetTheLeastOf(leadingSpaceCountList);
                if (theLeast > 0)
                    needFormat = true;
            }

            return needFormat;
        }

        public bool IsTabFormatNeeded(string RTFText)
        {
            List<int> leadingTabCountList = this.GetLeadingTabCountList(RTFText);
            int theLeast = 0;
            bool needFormat = false;

            if (leadingTabCountList.Count > 0)
            {
                theLeast = this.GetTheLeastOf(leadingTabCountList);
                if (theLeast > 0)
                    needFormat = true;
            }

            return needFormat;
        }

        private int GetTheLeastOf(List<int> intList)
        {
            int least = int.MaxValue;

            foreach (int item in intList)
            {
                if (item < least)
                    least = item;
            }

            return least;
        }
    }
}
